package com.logistics.dictionary.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.logistics.dictionary.entity.domain.Dictionary;
import com.logistics.dictionary.entity.model.DictionaryPager;
import com.logistics.dictionary.entity.model.DictionaryRow;
import com.logistics.dictionary.entity.model.DictionarySave;
import com.logistics.dictionary.mapper.DictionaryMapper;
import com.logistics.organization.entity.domain.Organization;
import com.logistics.utils.aspect.annotation.Insert;
import com.logistics.utils.aspect.annotation.Pager;
import com.logistics.utils.bean.ResultPager;
import com.logistics.utils.constants.Message;
import com.logistics.utils.exception.MessageException;
import com.logistics.utils.message.Manager;
import com.logistics.utils.tool.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class DictionaryService extends ServiceImpl<DictionaryMapper, Dictionary> {


    /**
     * 分页查找列表
     * @param param
     * @return
     */
    @Pager
    public ResultPager<DictionaryRow> pager(DictionaryPager param){
        IPage page = new Page(param.getCurrent(), param.getPageSize());
        QueryWrapper<Dictionary> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Dictionary::getParentId, 0);
        if(StringUtils.isNotNull(param.getName())){
            queryWrapper.lambda().like(Dictionary::getName, param.getName());
        }
        if(StringUtils.isNotNull(param.getCode())){
            queryWrapper.lambda().eq(Dictionary::getCode, param.getCode());
        }
        if(StringUtils.isNotNull(param.getLanguage())){
            queryWrapper.lambda().eq(Dictionary::getLanguage, param.getLanguage());
        }
        IPage<Dictionary> result = this.page(page, queryWrapper.lambda().orderByDesc(Dictionary::getCreateTime));
        return new ResultPager<>(dataFormatter(result.getRecords()), (int)result.getTotal());
    }

    /**
     * 根据类型查找
     * @param types
     * @return
     */
    public List<DictionaryRow> listByTypes(String types) throws MessageException {
        if(StringUtils.isNull(types)){
            throw new MessageException(Manager.getMessage(Message.MSG1006.getCode()));
        }
        return dataFormatter(this.list(new LambdaQueryWrapper<Dictionary>().in(Dictionary::getCode,
                StringUtils.splitToList(types, ","))));
    }

    /**
     * 查询详细
     * @param id
     * @return
     * @throws MessageException
     */
    public DictionaryRow details(String id) throws MessageException {
        if(StringUtils.isNull(id)){
            throw new MessageException(Manager.getMessage(Message.MSG1005.getCode()));
        }
        Dictionary row = this.getOne(new QueryWrapper<Dictionary>().lambda().eq(Dictionary::getId, id));
        return DictionaryRow.build(row);
    }

    /**
     * 查找所有
     * @return
     */
    public List<DictionaryRow> allList(){
        return dataFormatter(this.list(new QueryWrapper<Dictionary>().lambda().eq(Dictionary::getParentId, 0)));
    }

    /**
     * 添加
     * @param save
     */
    @Insert
    @Transactional
    public void save(DictionarySave save){
        if(StringUtils.isNull(save.getId())){
            this.save(Dictionary.build(save));
        }else{
            this.update(Dictionary.build(save),
                    new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getId, save.getId()));
        }
    }

    /**
     * 删除
     * @param ids
     */
    public void delete(String ids) throws MessageException {
        if(StringUtils.isNull(ids)){
            throw new MessageException(Manager.getMessage(Message.MSG1005.getCode()));
        }
        this.remove(new LambdaQueryWrapper<Dictionary>().in(Dictionary::getId, StringUtils.splitToList(ids, ",")));
    }

    /**
     * 获取字典子
     * @param id
     * @param allList
     * @return
     */
    private List<DictionaryRow> getChildren(Integer id, List<Dictionary> allList){
        return allList.stream().filter(e -> e.getParentId() == id).map(e -> DictionaryRow.build(e)).collect(Collectors.toList());
    }

    /**
     * 数据转换
     * @param rows
     * @return
     */
    private List<DictionaryRow> dataFormatter(List<Dictionary> rows){
        List<Integer> ids = rows.stream().map(e -> e.getId()).collect(Collectors.toList());
        List<Dictionary> allList = ids.size() > 0 ? this.list(new LambdaQueryWrapper<Dictionary>().in(Dictionary::getParentId, ids)) :
                new ArrayList<>();
        return rows.stream().map(e -> DictionaryRow.build(e))
                .map(e -> {
                    e.setChildren(getChildren(e.getId(), allList));
                    return e;
                }).collect(Collectors.toList());
    }

    /**
     * 根据code获取子项
     * @param code
     * @return
     * @throws MessageException
     */
    public List<DictionaryRow> getChildrenByCode(String code) throws MessageException {
        if(StringUtils.isNull(code)){
            throw new MessageException(Manager.getMessage(Message.MSG1006.getCode()));
        }
        Dictionary parent = this.getOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, code)
                .in(Dictionary::getCode, code));
        List<Dictionary> list = this.list(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getParentId, parent.getId()));
        return dataFormatter(list);
    }

}
